package com.smartfactory.sail.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartfactory.sail.entity.*;
import com.smartfactory.sail.mapper.*;
import com.smartfactory.sail.service.IItemWorkingprocedureService;
import com.smartfactory.sail.service.IWasteService;
import com.smartfactory.sail.vo.item.ItemWorkingprocedureResp;
import com.smartfactory.sail.vo.item.ItemWorkingprocedureSimpleResp;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.stream.Collectors;

/**
 * <p>
 * 产品工序表 服务实现类
 * </p>
 *
 * @author 王巨壁
 * @since 2019-08-13
 */
@Service
public class ItemWorkingprocedureServiceImpl extends ServiceImpl<ItemWorkingprocedureMapper, ItemWorkingprocedure> implements IItemWorkingprocedureService {
    private ItemWorkingprocedureMapper itemWorkingprocedureMapper;
    private OrderItemMapper orderItemMapper;
    private StorageRecordMapper storageRecordMapper;
    private ItemMapper itemMapper;
    private IWasteService iWasteService;

    public ItemWorkingprocedureServiceImpl(ItemWorkingprocedureMapper itemWorkingprocedureMapper, OrderItemMapper orderItemMapper, StorageRecordMapper storageRecordMapper, ItemMapper itemMapper, IWasteService iWasteService) {
        this.itemWorkingprocedureMapper = itemWorkingprocedureMapper;
        this.orderItemMapper = orderItemMapper;
        this.storageRecordMapper = storageRecordMapper;
        this.itemMapper = itemMapper;
        this.iWasteService = iWasteService;
    }

    @Override
    public List<ItemWorkingprocedure> findByItemId(long itemId, long dept) {
        LambdaQueryWrapper<ItemWorkingprocedure> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ItemWorkingprocedure::getItemId, itemId);
        queryWrapper.eq(ItemWorkingprocedure::getDept, dept);
        return itemWorkingprocedureMapper.selectList(queryWrapper);
    }

    @Override
    public List<ItemWorkingprocedureResp> detail(long orderId, long itemId, long dept) {
        List<ItemWorkingprocedureResp> detail = itemWorkingprocedureMapper.detail(orderId, itemId, dept);
        LambdaQueryWrapper<OrderItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(OrderItem::getItemId, itemId);
        queryWrapper.eq(OrderItem::getOrderId, orderId);
        OrderItem orderItem = orderItemMapper.selectOne(queryWrapper);
        Integer size = orderItem.getSize();
        Item item = itemMapper.selectById(orderItem.getItemId());
        Integer scrapRate = item.getScrapRate();
        for (ItemWorkingprocedureResp workingprocedureResp : detail) {
            int completeNumber = workingprocedureResp.getInfos().stream()
                    .filter(itemWorkingprocedureInfo -> itemWorkingprocedureInfo.getCompleteNumber() != null)
                    .mapToInt(ItemWorkingprocedureInfo::getCompleteNumber).sum();

            int problemNumber = workingprocedureResp.getInfos().stream()
                    .filter(itemWorkingprocedureInfo -> itemWorkingprocedureInfo.getProblemNumber() != null)
                    .mapToInt(ItemWorkingprocedureInfo::getProblemNumber).sum();
            workingprocedureResp.setCompletedNumber(completeNumber);
            workingprocedureResp.setProblemNumber(problemNumber);
            workingprocedureResp.setTotalNumber(size);
            workingprocedureResp.setScrapRate(scrapRate);

            int wastePreSum = iWasteService.wastePreSum(workingprocedureResp.getItemId(), workingprocedureResp.getOrderId(), workingprocedureResp.getId());
            workingprocedureResp.setWasteNumber(wastePreSum);
        }
        return detail;
    }

    @Override
    public List<ItemWorkingprocedureSimpleResp> simple(long orderId, long itemId, long dept) {
        List<ItemWorkingprocedureResp> detail = detail(orderId, itemId, dept);
        return detail.stream().map(itemWorkingprocedureResp -> {
            ItemWorkingprocedureSimpleResp itemWorkingprocedureSimpleResp = new ItemWorkingprocedureSimpleResp();
            BeanUtils.copyProperties(itemWorkingprocedureResp, itemWorkingprocedureSimpleResp);
            Integer completedNumber = itemWorkingprocedureSimpleResp.getCompletedNumber();
            Integer totalNumber = itemWorkingprocedureSimpleResp.getTotalNumber();
            itemWorkingprocedureSimpleResp.setRatio(Math.toIntExact(Math.round(completedNumber * 1.0 / totalNumber * 100)));
            return itemWorkingprocedureSimpleResp;
        }).collect(Collectors.toList());
    }

    @Override
    public double orderProgress(long orderId) {
        List<ItemWorkingprocedureResp> detail = itemWorkingprocedureMapper.progress(orderId, null, null);
        OptionalDouble average = detail.stream().mapToDouble(itemWorkingprocedureResp -> {
            OrderItem orderItem = orderItemMapper.getOneByOrderIdAndItemId(orderId, itemWorkingprocedureResp.getItemId());
            Integer completedNumber = itemWorkingprocedureResp.getInfos().stream()
                    .filter(itemWorkingprocedureInfo -> itemWorkingprocedureInfo.getCompleteNumber() != null)
                    .mapToInt(ItemWorkingprocedureInfo::getCompleteNumber).sum();
            Integer totalNumber = orderItem.getSize();
            return Math.toIntExact(Math.round(completedNumber * 1.0 / totalNumber * 100));
        }).average();
        return average.isPresent() ? average.getAsDouble() : 0;
    }

    @Override
    public boolean isLastWp(long itemId, long workingProcedureId, long dept) {
        List<ItemWorkingprocedure> workingprocedures = findByItemId(itemId, dept);
        Optional<ItemWorkingprocedure> max = workingprocedures.stream().max(Comparator.comparingInt(ItemWorkingprocedure::getSort));
        return max.isPresent() && max.get().getId().equals(workingProcedureId);
    }

    /**
     * 判断orderItem是否已经完成生产
     * @param orderItemIId
     * @return
     */
    @Override
    public boolean isComplate(Long orderItemIId) {

        OrderItem orderItem = orderItemMapper.selectById(orderItemIId);
        Integer orderSize = orderItem.getSize();

        QueryWrapper<StorageRecord> query = new QueryWrapper<>();
        query.eq("itemId", orderItem.getItemId()).eq("orderId", orderItem.getOrderId());
        List<StorageRecord> records = storageRecordMapper.selectList(query);
        if (records == null || records.size() == 0) {
            return false;
        }

        //storage_record 里面所有的总数
        int storageRecordNum = 0;
        for (StorageRecord record : records) {
            storageRecordNum += record.getSize();
        }

        if (orderSize <= storageRecordNum) {
            return true;
        } else {
            //报废的总数
            QueryWrapper<Waste> wasteQueryWrapper = new QueryWrapper<>();
            wasteQueryWrapper.eq("itemId", orderItem.getItemId()).eq("orderId", orderItem.getOrderId());
            List<Waste> wastes = iWasteService.list(wasteQueryWrapper);
            if (wastes == null || wastes.size() == 0) {
                return false;
            } else {
                int totalWastesNum = 0;
                for (Waste waste : wastes) {
                    totalWastesNum += waste.getSize();
                }
                if ((storageRecordNum + totalWastesNum) >= orderSize) {
                    return true;
                } else {
                    return false;
                }
            }

        }
    }
}
